import Axios, {
    AxiosHeaders,
    type AxiosInstance,
    type AxiosRequestConfig, AxiosResponse,
    type CustomParamsSerializer
} from "axios";
import type {
    PureHttpError,
    RequestMethods,
    PureHttpResponse,
    PureHttpRequestConfig
} from "./types.d";
import { stringify } from "qs";

// 相关配置请参考：www.axios-js.com/zh-cn/docs/#axios-request-config-1
const defaultConfig: AxiosRequestConfig = {
    // 请求超时时间
    timeout: 10000,
    baseURL: process.env.EXPO_PUBLIC_API_URL,
    // baseURL: 'http://192.168.10.122:8080/',
    headers: {
        Accept: "application/json, text/plain, */*",
        "Content-Type": "application/json",
        "X-Requested-With": "XMLHttpRequest"
    },
    // 数组格式参数序列化（https://github.com/axios/axios/issues/5142）
    paramsSerializer: {
        serialize: stringify as unknown as CustomParamsSerializer
    }
};

class PureHttp {
    constructor() {
        this.httpInterceptorsRequest();
        this.httpInterceptorsResponse();
    }

    /** `token`过期后，暂存待执行的请求 */
    private static requests = [];

    /** 防止重复刷新`token` */
    private static isRefreshing = false;

    /** 初始化配置对象 */
    private static initConfig: PureHttpRequestConfig = {};

    /** 保存当前`Axios`实例对象 */
    private static axiosInstance: AxiosInstance = Axios.create(defaultConfig);

    /** 重连原始请求 */
    private static retryOriginalRequest(config: PureHttpRequestConfig) {
        return new Promise(resolve => {
            PureHttp.requests.push((token: string) => {
                if (config.headers instanceof AxiosHeaders) {
                    config.headers["Authorization"] = `Bearer ljy123456`;
                }
                resolve(config);
            });
        });
    }

    /** 请求拦截 */
    private httpInterceptorsRequest(): void {
        PureHttp.axiosInstance.interceptors.request.use(
            (config: AxiosRequestConfig) => {
                // 在这里可以添加例如token等请求头
                config.headers['Authorization'] = `Bearer ljy123456`;
                return config;
            },
            (error) => {
                // 请求错误处理

                const {response} = error;
                // 处理 HTTP 网络错误
                let message = '';

                // HTTP 状态码
                const status = response?.status;

                switch (status) {
                    case 401:
                        message = 'token 失效，请重新登录';
                        // 这里可以触发退出的 action
                        break;
                    case 403:
                        message = '拒绝访问';
                        break;
                    case 404:
                        message = '请求地址错误';
                        break;
                    case 500:
                        message = '服务器故障';
                        break;
                    default:
                        message = '网络连接故障';
                }

                console.log(message, "response-error-msg")

                return Promise.reject(error);
            },
        );
    }

    /** 响应拦截 */
    private httpInterceptorsResponse(): void {
        const instance = PureHttp.axiosInstance;
        instance.interceptors.response.use(
            (response: AxiosResponse) => {
                // 对响应数据做处理，例如只返回data部分
                return response.data;
            },
            (error) => {
                // 响应错误处理
                return Promise.reject(error);
            },
        );
    }

    /** 通用请求工具函数 */
    public request<T>(
        method: RequestMethods,
        url: string,
        param?: AxiosRequestConfig,
        axiosConfig?: PureHttpRequestConfig
    ): Promise<T> {
        const config = {
            method,
            url,
            ...param,
            ...axiosConfig
        } as PureHttpRequestConfig;

        // 单独处理自定义请求/响应回调
        return new Promise((resolve, reject) => {
            PureHttp.axiosInstance
                .request(config)
                .then((response: undefined) => {
                    resolve(response);
                })
                .catch(error => {
                    reject(error);
                });
        });
    }

    /** 单独抽离的`post`工具函数 */
    public post<T, P>(
        url: string,
        params?: AxiosRequestConfig<P>,
        config?: PureHttpRequestConfig
    ): Promise<T> {
        return this.request<T>("post", url, params, config);
    }

    /** 单独抽离的`get`工具函数 */
    public get<T, P>(
        url: string,
        params?: AxiosRequestConfig<P>,
        config?: PureHttpRequestConfig
    ): Promise<T> {
        return this.request<T>("get", url, params, config);
    }
}

export const http = new PureHttp();
